/**
 * data中url定义 add为新增接口  edit为编辑接口
 * 表单组件ref定义为ruleForm
 * formkeys定义为表单字段
 */
import pick from 'lodash/pick'
import { httpAction, getAction } from '@/services/manage'
import { CURY_TYPE } from '@/store/mutation-types'
export default {
  data() {
    return {
      title: '新增',
      visible: false,
      model: {},
      form: {},
      labelCol: {
        xs: { span: 24 },
        sm: { span: 6 }
      },
      wrapperCol: {
        xs: { span: 24 },
        sm: { span: 17 }
      },
      confirmLoading: false,
      disableSubmit: false,
      fullscreen: false,
      switchFullscreen: true,
      formkeys: [], // 去除form不需要字段
      editType: ''
    }
  },
  computed: {
    vxeTableOption() {
      const defaultToolbarConfig = {
        buttons: [
          { buttonRender: { name: 'VxeToolbarAdd', events: { click: this.handleAdd }, disabled: this.disableSubmit }},
          { buttonRender: { name: 'VxeToolbarDel', events: { click: this.batchDel }, disabled: this.disableSubmit }}
        ],
        perfect: true,
        'class-name': 'z-vxe-toolbar'
      }
      /*
      *customTableToolbar为页面需要自定义的toolbar配置
      *也可以直接在页面组件使用时直接定义属性覆盖该配置
      */
      const toolbarConfig = Object.assign({ }, defaultToolbarConfig, this.customTableToolbar)
      return {
        border: true,
        resizable: true,
        'keep-source': true,
        'max-height': 500,
        'edit-config': this.disableSubmit ? false : { trigger: 'click', mode: 'cell', showStatus: true, autoClear: false },
        'checkbox-config': { checkMethod: () => !this.disableSubmit },
        toolbarConfig: toolbarConfig
      }
    },
    modalOption() {
      return {
        title: this.title,
        destroyOnClose: true,
        width: '80%',
        visible: this.visible,
        'fullscreen.sync': this.fullscreen,
        'switchFullscreen': this.switchFullscreen,
        confirmLoading: this.confirmLoading,
        cancelText: '关闭',
        afterClose: this.afterClose,
        okButtonProps: { class: { '!hidden': this.disableSubmit }}
      }
    }
  },
  methods: {
    async handleOk() {
      try {
        // 校验主表单及子表
        await this.getAllValidate()
        this.confirmLoading = true
        // 提交前后事件处理 需要阻止继续执行 需要返回异步Promise new Promise((resolve, reject)=>{ reject({message:'我是错误信息'}) }) 提示信息可以放到reject处理，也可自己处理
        if (typeof this.submitBefore === 'function') await this.submitBefore()
        const formData = this.classifyIntoFormData ? this.classifyIntoFormData() : Object.assign(this.form, { crudType: this.editType === 'add' ? CURY_TYPE.SAVE : CURY_TYPE.UPDATE })
        const res = await this.request(formData)
        this.confirmLoading = false
        if (res.success) {
          // 提交后事件处理
          typeof this.submitAfter === 'function' ? await this.submitAfter(res) : this.defaultCallback(res)
        }
        // else {
        //   this.$message.warning(res.message)
        // }
      } catch (error) {
        this.confirmLoading = false
        if (error && typeof error === 'object') {
          const { message, key } = error
          message ? this.$message.warning(message) : ''
          key ? this.activeKey = key : '' // 校验失败后，切换至校验失败tab
        }
        console.error(error)
      }
    },
    defaultCallback(res) {
      this.$message.success(res.message)
      this.$emit('ok')
      this.close()
    },
    getAllValidate() {
      const values = []
      if ((this.refKeys instanceof Array)) {
        this.refKeys.forEach(key => {
          const target = this.$refs[key]
          if (target) {
            target.$vnode.tag.indexOf('VxeGrid') >= 0 ? values.push(this.tableValidate(target, key)) : values.push(this.formValidate(target, key))
          }
        })
      }
      this.$refs.ruleForm && values.push(this.$refs.ruleForm.validate())
      return Promise.all(values)
    },
    formValidate(target, key) {
      return new Promise((resolve, reject) => {
        target.validate(valid => {
          if (!valid) {
            reject({ key })// 校验不通过返回对应tab
          }
          resolve(true)
        })
      })
    },
    tableValidate(target, key) { // 修改vxetable校验返回值与form一致
      return new Promise((resolve, reject) => {
        target.validate(true, err => {
          if (err) {
            reject({ key })// 校验不通过返回对应tab
          }
          resolve(true)
        })
      })
    },
    handleCancel() {
      this.close()
    },
    async add(data) {
      try {
        this.editType = 'add'
        // 新增前后事件处理 需要阻止继续执行 需要返回异步Promise new Promise((resolve, reject)=>{ reject('我是错误信息') }) 提示信息可以放到reject处理，也可自己处理
        if (typeof this.addBefore === 'function') await this.addBefore(data)
        this.title = '新增'
        this.visible = true
        if (typeof this.addAfter === 'function') await this.addAfter(data)
      } catch (error) {
        error && typeof error === 'string' && this.$message.warning(error)
        console.log(error)
      }
    },
    async edit(data) {
      try {
        this.editType = 'edit'
        // 编辑前后事件处理 需要阻止继续执行 需要返回异步Promise new Promise((resolve, reject)=>{ reject('我是错误信息') }) 提示信息可以放到reject处理，也可自己处理
        if (typeof this.editBefore === 'function') await this.editBefore(data)
        this.title = '编辑'
        this.model = Object.assign({}, data)
        this.visible = true
        this.form = this.formkeys && this.formkeys.length > 0 ? pick(this.model, [...this.formkeys]) : Object.assign({}, data)
        if (typeof this.editAfter === 'function') await this.editAfter(this.model)
      } catch (error) {
        error && typeof error === 'string' && this.$message.warning(error)
        console.log(error)
      }
    },
    close() {
      this.$emit('close')
      this.model = {}
      this.form = {}
      this.$refs.ruleForm && this.$refs.ruleForm.resetFields()
      this.visible = false
      // this.disableSubmit = false
    },
    request(formData) {
      let url = this.url.add; let method = 'post'
      if (this.editType === 'edit') {
        url = this.url.edit
        method = 'put'
      }
      this.confirmLoading = true
      return httpAction(url, formData, method)
    },
    async handleAdd(key, target) {
      // 获取表格插入数据
      const insertData = typeof this.getInsertData === 'function' ? await this.getInsertData() : {}
      target.insert(insertData).then(({ row }) => {
        target.setActiveRow(row)
      })
    },
    batchDel(key, target) {
      target.removeCheckboxRow()
    },
    createdVxeTableData(tableKey, dataSource) { // 解决vxe-table数据无列字段时,编辑表格数据无法双向绑定bug
      const $table = this.$refs[tableKey]
      $table.createData(dataSource).then(list => {
        $table.loadData(list)
      })
    },
    afterClose() {
      Object.assign(this.$data, this.$options.data.call(this))
    },
    setDataCrud(records) { // 设置提交数据脏数据状态
      const { insertRecords, removeRecords, updateRecords } = records
      if (this.editType === 'edit') {
        insertRecords && insertRecords.forEach(item => {
          item.crudType = CURY_TYPE.SAVE
        })
        removeRecords && removeRecords.forEach(item => {
          item.crudType = CURY_TYPE.DELETE
        })
        updateRecords && updateRecords.forEach(item => {
          item.crudType = CURY_TYPE.UPDATE
        })
        return [].concat(insertRecords, removeRecords, updateRecords)
      } else { // 主单新增时，默认子表都为新增
        insertRecords && insertRecords.forEach(item => {
          item.crudType = CURY_TYPE.SAVE
        })
        updateRecords && updateRecords.forEach(item => {
          item.crudType = CURY_TYPE.SAVE
        })
        return [].concat(insertRecords, updateRecords)
      }
    },
    /** 查询某个tab的数据 */
    requestSubTableData(url, params, tab, success) {
      return getAction(url, params).then(res => {
        if (res.success) {
          tab.dataSource = res.result
        }
        typeof success === 'function' ? success(res) : ''
      })
    }
  }
}

